package com.ruoyi.web.controller.biz;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.ruoyi.biz.domain.TTestCaseInfo;
import com.ruoyi.biz.service.ITTestCaseInfoService;
import com.ruoyi.biz.task.ParsingXMLTask;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 【请填写功能名称】Controller
 *
 * @author jiangnan
 * @date 2021-03-12
 */
@Slf4j
@Controller
@RequestMapping("/biz/info")
public class TTestCaseInfoController extends BaseController {
    private String prefix = "biz/info";

    @Autowired
    private ITTestCaseInfoService tTestCaseInfoService;
    @Autowired
    private ParsingXMLTask parsingXMLTask;

    @RequiresPermissions("biz:info:view")
    @GetMapping()
    public String info() {
        return prefix + "/info";
    }

    /**
     * 查询【请填写功能名称】列表
     */
    @RequiresPermissions("biz:info:list")
    @PostMapping("/list")
    @ResponseBody
    public TableDataInfo list(TTestCaseInfo tTestCaseInfo) {
        startPage();
        List<TTestCaseInfo> list = tTestCaseInfoService.selectTTestCaseInfoList(tTestCaseInfo);
        return getDataTable(list);
    }

    @RequiresPermissions("biz:info:list")
    @PostMapping("/listDetail")
    @ResponseBody
    public List<TTestCaseInfo> listDetail(TTestCaseInfo tTestCaseInfo) {
        return tTestCaseInfoService.selectTTestCaseInfoList(tTestCaseInfo);
    }

    /**
     * 修改【请填写功能名称】
     */
    @RequiresPermissions("biz:info:list")
    @GetMapping("/detail/{id}")
    public String listDetail(@PathVariable("id") Long id, ModelMap mmap) {
        TTestCaseInfo tTestCaseInfo = tTestCaseInfoService.selectTTestCaseInfoById(id);
        mmap.put("tTestCaseInfo", tTestCaseInfo);
        return prefix + "/detail";
    }


    @RequiresPermissions("biz:info:list")
    @GetMapping("/getTotal")
    @ResponseBody
    public Map<String, Object> getTotal(TTestCaseInfo tTestCaseInfo) {
        Map<String, Object> map = new HashMap<>();
        setTotal(tTestCaseInfo, map);
        return map;
    }

    /**
     * 新增【请填写功能名称】
     */
    @GetMapping("/add")
    public String add() {
        parsingXMLTask.parsingXmlAll();
        return prefix + "/add";
    }


    @RequiresPermissions("biz:info:export")
    @Log(title = "根据行数据导出", businessType = BusinessType.EXPORT)
    @GetMapping("/exportRows")
    public void exportRows(String ids, HttpServletResponse response) throws IOException {
        if (StrUtil.isNotBlank(ids)) {
            response.setContentType("application/octet-stream");//
            response.setHeader("content-type", "application/octet-stream");
            response.setHeader("Content-Disposition", "attachment;fileName=" + new String("合规性信息安全测试报告.xls".getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));// 设置文件名
            TemplateExportParams params = new TemplateExportParams(
                    "合规性信息安全测试报告-模板.xls", true);
            Map<String, Object> map = new HashMap();
            String[] childIds = StrUtil.split(ids, ",");
            List<TTestCaseInfo> tTestCaseInfos = tTestCaseInfoService.getInfoListInChildIds(childIds);
            Map<String, Object> infoTime = tTestCaseInfoService.getInfoTimeInChildIds(childIds);
            if (StrUtil.isNotBlank(MapUtil.getStr(infoTime, "beginDate"))) {
                map.put("beginDate", DateUtil.formatDateTime(MapUtil.getDate(infoTime, "beginDate")));
            } else {
                map.put("beginDate", "");
            }
            if (StrUtil.isNotBlank(MapUtil.getStr(infoTime, "endDate"))) {
                map.put("endDate", DateUtil.formatDateTime(MapUtil.getDate(infoTime, "endDate")));
            } else {
                map.put("endDate", "");
            }
            // TODO 暂时取消
            map.put("type", "");
            map.put("version", "");
            // 设置caseList数据
            List<Map<String, Object>> data = new ArrayList<>();
            setCaseChildList(data, tTestCaseInfos);
            map.put("caseList", data);
            // 设置数量
            map.put("total", tTestCaseInfoService.getCaseTotalInChildIds(childIds));
            map.put("executeTotal", tTestCaseInfoService.getCaseExecuteTotalInChildIds(childIds));
            map.put("failTotal", tTestCaseInfoService.getCaseFailTotalInChildIds(childIds));
            Workbook workbook = ExcelExportUtil.exportExcel(params, map);
            ServletOutputStream outputStream = response.getOutputStream();
            workbook.write(outputStream);
            outputStream.close();
        }
    }


    @RequiresPermissions("biz:info:export")
    @Log(title = "根据查询条件导出", businessType = BusinessType.EXPORT)
    @GetMapping("/export")
    public void export(TTestCaseInfo tTestCaseInfo, HttpServletResponse response) throws IOException {
        response.setContentType("application/octet-stream");
        response.setHeader("content-type", "application/octet-stream");
        response.setHeader("Content-Disposition", "attachment;fileName=" + new String("合规性信息安全测试报告.xls".getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));// 设置文件名
        TemplateExportParams params = new TemplateExportParams(
                "合规性信息安全测试报告-模板.xls", true);
        // 设置excel参数
        Map<String, Object> map = new HashMap();
        // TODO 暂时取消
        map.put("type", "");
        map.put("version", "");
        // 设置开始时间和结束时间
        setTime(tTestCaseInfo, map);
        // 设置caseList数据
        setCaseInfoList(tTestCaseInfo, map);
        setTotal(tTestCaseInfo, map);

        Workbook workbook = ExcelExportUtil.exportExcel(params, map);
        ServletOutputStream outputStream = response.getOutputStream();
        workbook.write(outputStream);
        outputStream.close();
    }

    /**
     * 设置开始时间和结束时间
     *
     * @param tTestCaseInfo
     * @param map
     */
    private void setTime(TTestCaseInfo tTestCaseInfo, Map<String, Object> map) {
        TTestCaseInfo info = new TTestCaseInfo();
        info.setVersion(tTestCaseInfo.getVersion());
        info.setType(tTestCaseInfo.getType());
        info.setRootFlag("0");
        Map<String, Object> paramsO = new HashMap<>();
        paramsO.put("beginTime", tTestCaseInfo.getBeginTime());
        paramsO.put("endTime", tTestCaseInfo.getBeginTime());
        info.setParams(paramsO);
        Map<String, Object> infoTime = tTestCaseInfoService.getInfoTime(tTestCaseInfo);
        if (StrUtil.isNotBlank(MapUtil.getStr(infoTime, "beginDate"))) {
            map.put("beginDate", DateUtil.formatDateTime(MapUtil.getDate(infoTime, "beginDate")));
        } else {
            map.put("beginDate", tTestCaseInfo.getBeginTime());
        }
        if (StrUtil.isNotBlank(MapUtil.getStr(infoTime, "endDate"))) {
            map.put("endDate", DateUtil.formatDateTime(MapUtil.getDate(infoTime, "endDate")));
        } else {
            map.put("endDate", tTestCaseInfo.getBeginTime());
        }
    }

    /**
     * 设置caseList数据
     *
     * @param info
     * @param map
     */
    private void setCaseInfoList(TTestCaseInfo info, Map<String, Object> map) {
        // 表格数据集合
        List<Map<String, Object>> data = new ArrayList<>();
        // 根据查询条件查询
        List<TTestCaseInfo> tTestCaseInfos = tTestCaseInfoService.selectTTestCaseInfoListByInfo(info);
        // 设置子集集合
        setCaseChildList(data, tTestCaseInfos);
        map.put("caseList", data);
    }

    /**
     * 设置子集集合
     *
     * @param data
     * @param tTestCaseInfos
     */
    private void setCaseChildList(List<Map<String, Object>> data, List<TTestCaseInfo> tTestCaseInfos) {
        if (CollUtil.isNotEmpty(tTestCaseInfos)) {
            Map<String, Object> mapInfo;
            for (int i = 0; i < tTestCaseInfos.size(); i++) {
                TTestCaseInfo rootInfo = tTestCaseInfos.get(i);
                // 最外层的
                mapInfo = new HashMap<>();
                // 一级num
                int num = i + 1;
                mapInfo.put("num", num);
                mapInfo.put("des", rootInfo.getDescription());
                mapInfo.put("suffix", rootInfo.getSuffix());
                mapInfo.put("error", "");
                data.add(mapInfo);
                // case数据
                String rootId = rootInfo.getRootId();
                List<TTestCaseInfo> caseChildInfos = tTestCaseInfoService.getInfoListByRootId(rootId);
                Map<String, Object> mapChild;
                for (int j = 0; j < caseChildInfos.size(); j++) {
                    // 子级数据
                    TTestCaseInfo caseChild = caseChildInfos.get(j);
                    mapChild = new HashMap<>();
                    mapChild.put("num", (num + "." + (j + 1)));
                    mapChild.put("des", caseChild.getDescription());
                    mapChild.put("suffix", caseChild.getSuffix());
                    // 有错误
                    if ("Fail".equalsIgnoreCase(caseChild.getSuffix())) {
                        TTestCaseInfo infoByParentId = tTestCaseInfoService.getInfoByParentId(caseChild.getChildId());
                        if (infoByParentId != null) {
                            mapChild.put("error", infoByParentId.getDescription());
                        }
                    } else {
                        mapChild.put("error", "");
                    }
                    data.add(mapChild);
                }
            }
        }
    }

    /**
     * 根据查询条件查询数量
     *
     * @param tTestCaseInfo
     * @param map
     */
    private void setTotal(TTestCaseInfo tTestCaseInfo, Map<String, Object> map) {
        map.put("total", tTestCaseInfoService.getCaseTotal(tTestCaseInfo));
        map.put("executeTotal", tTestCaseInfoService.getCaseExecuteTotal(tTestCaseInfo));
        map.put("failTotal", tTestCaseInfoService.getCaseFailTotal(tTestCaseInfo));
    }
}
